home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 51 / Amiga Format CD51 (2000-03-10)(Future Publishing)(GB)[!][issue 2000-04].iso / -in_the_mag- / pdselect / blizkick / applypatch.e < prev    next >
Text File  |  2000-02-16  |  12KB  |  515 lines

  1. -> FILE: ESrc:Own/applypatch.e          REV: 5 --- apply BlizKick patch module to rom
  2. /* History
  3.    0      started 11th Dec 1999.
  4.    1      works.
  5.    2      12th Dec: added SPEEDROM
  6.    3      added HOGWAITBLIT
  7.    4      added test for <>$f80000 rom
  8.    5      no longer requires MODULES arg, now tests if any patches
  9.           was applied.
  10. */
  11.  
  12. /*
  13.   DESCRIPTION
  14.  
  15.     applypatch can be used to apply BlizKick "patch" kind of modules
  16.     to rom image. Useful if BlizKick doesn't support your system for
  17.     some reason, but you have a working maprom tool for it. applypatch
  18.     can also be used to speed up BlizKick booting by pre-patching rom
  19.     image. BlizKick commandline also gets quite a bit cleaner then. ;)
  20.  
  21.  
  22.   FEATURES
  23.  
  24.   - support for all patch modules that don't try to add resident tags
  25.   - includes HOGWAITBLIT patch of BlizKick
  26.   - includes SPEEDROM patch of BlizKick (kicktag reconnect)
  27.  
  28.  
  29.   RESTRICTIONS
  30.  
  31.   - works only with 512k ROM, 256K is obsolete really
  32.   - requires about 520k memory for patching
  33.   - for obvious reasons there is no undo :)
  34.  
  35.  
  36.   NOTES
  37.  
  38.   - It's a fairly good idea to keep the original ROM images somewhere
  39.     safe
  40.  
  41.  
  42.   SAMPLE RUN
  43.  
  44.     > applypatch DEVS:rom40068.A1200 TO T:rom40068.A1200.patch HOGWAITBLIT \
  45.       SPEEDROM NoClick FixMath404 SpeedyIDE PatchMath020 romfixes
  46.     reading kickfile "DEVS:rom40068.A1200"...
  47.     rom image ok, applying patches...
  48.     applying hogwaitblit patch...
  49.     applying NoClick patch...
  50.     applying FixMath404 patch...
  51.     applying SpeedyIDE patch...
  52.     applying PatchMath020 patch...
  53.     Patched DiceC Mulu routine at offset $27748
  54.     applying romfixes patch...
  55.     applying speedrom patch...
  56.  
  57.     ---- total 7 patches applied ----
  58.     calculating new checksum for image... $412214A9
  59.     writing patched rom image to "T:rom40068.A1200.patch"...
  60.     done.
  61.  
  62.  
  63.   TODO
  64.  
  65.   - add support for non-EXTRESBUF InstallModule()
  66.   - add support for non-EXTRESBUF modules
  67.  
  68.  
  69.   AUTHOR & LEGAL CRAP
  70.  
  71.     applypatch is written by Harry "Piru" Sintonen 1999.
  72.     applypatch is public domain.
  73.  
  74. */
  75.  
  76.  
  77. OPT OSVERSION=33
  78.  
  79. MODULE 'exec/memory','dos/dos','dos/var'
  80. MODULE 'hardware/dmabits'
  81.  
  82. ENUM ARG_KICKFILE,ARG_TO,ARG_MODULE,ARG_FORCE,ARG_SPEEDROM,
  83.      ARG_HOGWAITBLIT,NUMARGS
  84.  
  85. DEF progname[64]:STRING,array[NUMARGS]:ARRAY OF LONG,
  86.     size=524288
  87.  
  88. PROC main()
  89.  
  90.   IF KickVersion(37)=0
  91.     WriteF('get real! this program requires kickstart 2.04+\n')
  92.     RETURN RETURN_FAIL
  93.   ENDIF
  94.  
  95.   GetProgramName(progname,63); SetStr(progname,StrLen(progname))
  96.  
  97. ENDPROC main2()
  98.  
  99. PROC main2()
  100.   DEF rdargs,r
  101.  
  102.   r:='$VER: applypatch 1.0.1 (21.12.99)'
  103.   FOR r:=0 TO NUMARGS-1; array[r]:=0; ENDFOR
  104.   IF (rdargs:=ReadArgs('FROM=KICKFILE/A,TO/K/A,MODULE/M,FORCE/S,' +
  105.                        'SPEEDROM/S,HOGWAITBLIT/S',array,NIL))
  106.  
  107.     r:=main3(array[ARG_KICKFILE],array[ARG_MODULE])
  108.  
  109.     FreeArgs(rdargs)
  110.   ELSE
  111.     PrintFault(IoErr(),progname)
  112.     r:=RETURN_ERROR
  113.   ENDIF
  114. ENDPROC r
  115.  
  116. ENUM ROMSUMOFFS=$7FFE8,ROMSIZEOFFS=$7FFEC,ROMIDOFFS=$7FFF0,
  117.      BLIZKICK_ID="BlzK"
  118.  
  119. PROC main3(kickfile,modules:PTR TO LONG)
  120.   DEF r,rom:PTR TO LONG,fh,sum,suc=0,err=0
  121.   DEF modpath[256]:STRING,lock=NIL,olddir
  122.  
  123.   PrintF('reading kickfile "\s"...\n',kickfile)
  124.  
  125.   IF FileLength(kickfile)<>size
  126.     PrintF('kickfile "\s" length not \d\n',kickfile,size)
  127.     RETURN RETURN_ERROR
  128.   ENDIF
  129.  
  130.   IF (fh:=Open(kickfile,MODE_OLDFILE))=NIL
  131.     PrintFault(IoErr(),progname)
  132.     PrintF('could not open kickfile "\s"\n',kickfile)
  133.     RETURN RETURN_ERROR
  134.   ENDIF
  135.  
  136.   IF (rom:=New(size))=0
  137.     PrintFault(IoErr(),progname)
  138.     Close(fh)
  139.     PrintF('could not allocate \d bytes of memory\n',size)
  140.     RETURN RETURN_ERROR
  141.   ENDIF
  142.  
  143.   r:=Read(fh,rom,size); Close(fh); fh:=0
  144.   IF r<>size
  145.     PrintFault(IoErr(),progname)
  146.     PrintF('error reading kickfile "\s"\n',kickfile)
  147.     RETURN RETURN_ERROR
  148.   ENDIF
  149.  
  150.   IF (Long(rom+ROMSIZEOFFS)<>size) OR
  151.     ((rom[] AND $FFF8FFFF)<>$11104EF9)
  152.     PrintF('bad rom image!\n')
  153.     RETURN RETURN_ERROR
  154.   ENDIF
  155.  
  156.   r:=Long(rom+4) AND $FFFF0000
  157.   IF r<>$F80000
  158.     PrintF('rom image not located at $00F80000, but $\h[08]!\n',r)
  159.     RETURN RETURN_ERROR
  160.   ENDIF
  161.  
  162.   IF (sum:=romresum(rom,size))<>Long(rom+ROMSUMOFFS)
  163.     IF array[ARG_FORCE]
  164.       PrintF('bad rom checksum $\h[08] should be $\h[08], overrided ' +
  165.              'by FORCE/n',
  166.              sum,Long(rom+ROMSUMOFFS))
  167.     ELSE
  168.       PrintF('bad rom checksum $\h[08] should be $\h[08], can be\n' +
  169.              'overrided with FORCE switch\n',
  170.              sum,Long(rom+ROMSUMOFFS))
  171.       RETURN RETURN_ERROR
  172.     ENDIF
  173.   ENDIF
  174.  
  175.   IF Long(rom+ROMIDOFFS)=BLIZKICK_ID
  176.     IF array[ARG_FORCE]
  177.       PrintF('rom image has been used with BlizKick, but FORCE used\n')
  178.     ELSE
  179.       PrintF('rom image has been used with BlizKick before, can be\n' +
  180.              'overrided with FORCE switch\n')
  181.       RETURN RETURN_ERROR
  182.     ENDIF
  183.   ENDIF
  184.  
  185.   PrintF('rom image ok, applying patches...\n')
  186.  
  187.   -> apply hogwaitblit if enabled
  188.   IF array[ARG_HOGWAITBLIT]
  189.     PrintF('\e[1mapplying hogwaitblit patch...\e[22m\n')
  190.     IF puthogwaitblit(rom,size)
  191.       suc++
  192.     ELSE
  193.       err++
  194.       PrintF('could not patch!\n')
  195.     ENDIF
  196.   ENDIF
  197.  
  198.   IF modules
  199.     -> change dir to ENV:BKMODPATH
  200.  
  201.     IF GetVar('BKMODPATH',modpath,256,GVF_GLOBAL_ONLY)
  202.       IF (lock:=Lock(modpath,ACCESS_READ))
  203.         olddir:=CurrentDir(lock)
  204.       ENDIF
  205.     ENDIF
  206.  
  207.     -> process all modules
  208.  
  209.     WHILE modules[]
  210.       PrintF('\e[1mapplying \s patch...\e[22m\n',modules[]); Flush(stdout)
  211.       IF applypatch(modules[],rom,size) THEN suc++ ELSE err++
  212.       modules++
  213.     ENDWHILE
  214.  
  215.     -> back to orig dir
  216.  
  217.     IF lock
  218.       CurrentDir(olddir)
  219.       UnLock(lock); lock:=0
  220.     ENDIF
  221.  
  222.   ENDIF
  223.  
  224.   -> apply speedrom, if enabled
  225.   IF array[ARG_SPEEDROM]
  226.     PrintF('\e[1mapplying speedrom patch...\e[22m\n')
  227.     IF speedrom(rom,size)
  228.       suc++
  229.     ELSE
  230.       err++
  231.       PrintF('could not patch!\n')
  232.     ENDIF
  233.   ENDIF
  234.  
  235.   IF err
  236.     PrintF('\n\d patch\s failed, output file "\s" not written\n',
  237.            err,IF err=1 THEN '' ELSE 'es',array[ARG_TO])
  238.   ELSE
  239.  
  240.     IF suc=0
  241.       PrintF('\n---- total 0 patches applied ----\ndestination file "\s" not written!\n',
  242.              array[ARG_TO])
  243.     ELSE
  244.  
  245.       PrintF('\n---- total \d patch\s applied ----\ncalculating new checksum for image...',
  246.              suc,IF suc=1 THEN '' ELSE 'es')
  247.  
  248.       -> resum rom
  249.  
  250.       PutLong(rom+ROMSUMOFFS,sum:=romresum(rom,size))
  251.  
  252.       PrintF(' $\h[08]\nwriting patched rom image to "\s"...\n',sum,array[ARG_TO])
  253.  
  254.       -> write rom
  255.  
  256.       IF (fh:=Open(array[ARG_TO],MODE_NEWFILE))=NIL
  257.         PrintFault(IoErr(),progname)
  258.         PrintF('could not open file "\s" for writing\n',array[ARG_TO])
  259.         RETURN RETURN_ERROR
  260.       ENDIF
  261.  
  262.       r:=Write(fh,rom,size); Close(fh); fh:=0
  263.       IF r<>size
  264.         PrintFault(IoErr(),progname)
  265.         DeleteFile(array[ARG_TO])
  266.         PrintF('error writing to "\s", destination file deleted\n',array[ARG_TO])
  267.         RETURN RETURN_ERROR
  268.       ENDIF
  269.     ENDIF
  270.  
  271.   ENDIF
  272.  
  273.   PrintF('done.\n')
  274.  
  275. ENDPROC
  276.  
  277. PROC puthogwaitblit(rom,size)
  278.  
  279.   MOVEM.L D1-D7/A0-A6,-(A7)
  280.  
  281.   MOVE.L  rom,A0
  282.   MOVE.L  size,D0
  283.  
  284.   MOVEQ   #0,D7
  285.  
  286.   CMP.W   #39,$C(A0)         -> Requires rom 39+
  287.   BCS.B   phwb_exit
  288.  
  289.   LEA     -4(A0,D0.L),A1
  290.  
  291.   MOVE.L  #$08390006,D0
  292.   phwb_find:
  293.   ADDQ.L  #2,A0
  294.   CMPA.L  A1,A0
  295.   BEQ.B   phwb_exit
  296.   CMP.L   (A0),D0
  297.   BNE.B   phwb_find
  298.   CMP.L   #$00DFF002,4(A0)
  299.   BNE.B   phwb_find
  300.   CMP.L   #$66024E75,8(A0)
  301.   BNE.B   phwb_find
  302.  
  303.   CMP.L   #$08390006,-8(A0)  -> No KS 1.x!
  304.   BEQ.B   phwb_exit
  305.   CMP.L   #$4A3900DF,-6(A0)  -> KS 2.x/3.x:
  306.   BNE.B   phwb_exit
  307.   SUBQ.L  #6,A0
  308.   LEA     phwb_waitblit(PC),A1
  309.   MOVEQ   #21,D0             -> 42/2
  310.   phwb_copy:
  311.   MOVE.W  (A1)+,(A0)+
  312.   SUBQ.L  #1,D0
  313.   BNE.B   phwb_copy
  314.   MOVEQ   #1,D7
  315.  
  316.   phwb_exit:
  317.   MOVE.L  D7,D0
  318.   MOVEM.L (A7)+,D1-D7/A0-A6
  319.   RETURN  D0
  320.  
  321.   -> 3.0  48 bytes
  322.   -> 3.1  48 bytes
  323.   phwb_waitblit:
  324.   BTST    #6,$DFF002         -> 8 DMAB_BLTDONE=14 dmaconr
  325.   BNE.B   phwb_wb_gowait     -> 2
  326.   RTS                        -> 2
  327.   phwb_wb_gowait:
  328.   MOVE.L  A0,-(A7)           -> 2
  329.   LEA     $DFF002,A0         -> 6 dmaconr
  330.   MOVE.W  #$8400,148(A0)     -> 6 DMAF_SETCLR OR DMAF_BLITHOG dmacon-dmaconr
  331.   phwb_wb_wait:
  332.   BTST    #6,(A0)            -> 4 DMAB_BLTDONE=14 DMAB_BLTDONE-8
  333.   BNE.B   phwb_wb_wait       -> 2
  334.   MOVE.W  #$0400,148(A0)     -> 6 DMAF_BLITHOG dmacon-dmaconr
  335.   MOVE.L  (A7)+,A0           -> 2
  336.   RTS                        -> 2 =42
  337.  
  338. ENDPROC
  339.  
  340. PROC speedrom(rom,size)
  341.  
  342.   -> Reconnect resident modules:
  343.  
  344.   MOVEM.L D1-D7/A0-A6,-(A7)
  345.  
  346.   MOVE.L  rom,A0
  347.   MOVE.L  size,D0
  348.  
  349.   MOVE.L  #$01000000,D2
  350.   SUB.L   D0,D2
  351.   MOVE.L  A0,A5
  352.   SUB.L   D2,A5      -> a5=difference
  353.  
  354.   MOVEQ   #-28,D1    -> -(RT_SIZE+2),D1
  355.   ADD.L   D0,D1
  356.   SUB.L   A1,A1
  357.   sr_find:
  358.   SUBQ.L  #2,D1
  359.   BLS.B   sr_done
  360.   CMP.W   #$4AFC,(A0)+  -> RTC_MATCHWORD,(A0)+
  361.   BNE.B   sr_find
  362.   MOVEQ   #2,D0
  363.   ADD.L   (A0),D0    -> RT_MATCHTAG-2(A0),D0
  364.   ADD.L   A5,D0
  365.   CMP.L   A0,D0
  366.   BNE.B   sr_find
  367.   SUBQ.L  #2,A0
  368.   MOVE.L  A1,D0
  369.   BEQ.B   sr_is_1st
  370.   MOVE.L  A0,D0
  371.   SUB.L   A5,D0
  372.   MOVE.L  D0,6(A1)   -> RT_ENDSKIP(A1)
  373.   sr_is_1st:
  374.   MOVE.L  A0,A1
  375.   LEA     26(A0),A0  ->RT_SIZE(A0),A0
  376.   BRA.B   sr_find
  377.   sr_done:
  378.   MOVE.L  A1,D0
  379.   BEQ.B   sr_none
  380.   -> make last RT_ENDSKIP point $FFFFFE
  381.   MOVE.L  #$FFFFFE,6(A1)
  382.   sr_none:
  383.   MOVEQ   #1,D7
  384.  
  385.   MOVE.L  D7,D0
  386.   MOVEM.L (A7)+,D1-D7/A0-A6
  387. ENDPROC D0
  388.  
  389. ENUM BKMODULE_ID=$707A4E75,BKEP_ID=$4E71
  390.  
  391. PROC applypatch(patch,rom,size)
  392.   DEF ret=0,seg,module:PTR TO LONG
  393.  
  394.   IF (seg:=LoadSeg(patch))
  395.  
  396.     module:=Shl(seg,2)+4
  397.  
  398.     IF module[]=BKMODULE_ID
  399.       IF module[1]=BKEP_ID
  400.  
  401.         MOVEM.L D1-D7/A0-A6,-(A7)
  402.         LEA     findresident(PC),A2
  403.         LEA     installmodule(PC),A3
  404.         MOVE.L  dosbase,D6
  405.         MOVE.L  execbase,A6
  406.         MOVE.L  rom,A0
  407.         LEA     $F80000,A1
  408.         MOVE.L  #$80000,D0
  409.         MOVE.L  module,A5
  410.         LEA     printf(PC),A4
  411.         JSR     8(A5)
  412.         MOVEM.L (A7)+,D1-D7/A0-A6
  413.         MOVE.L  D0,ret
  414.  
  415.         IF ret=0
  416.           PrintF('failed, module returned error\n')
  417.         ENDIF
  418.  
  419.       ELSE
  420.         PrintF('failed, only patch modules supported!\n')
  421.       ENDIF
  422.     ELSE
  423.       PrintF('failed, not a blizkick module!\n')
  424.     ENDIF
  425.  
  426.     UnLoadSeg(seg)
  427.   ELSE
  428.     PrintFault(IoErr(),progname)
  429.     PrintF('failed, could not load segment!\n')
  430.   ENDIF
  431.   RETURN ret
  432.  
  433.  
  434. ->  IN: a0=ptr to ROM, d0=rom len, a1=ptr to resident name
  435. -> OUT: d0=ptr to resident (buf) or NULL
  436. findresident:
  437.   MOVEM.L D1-D7/A0-A6,-(A7)
  438.   MOVEQ   #1,D6
  439.   MOVE.L  A1,A3
  440.   MOVE.L  #$01000000,D2
  441.   SUB.L   D0,D2      -> d2=rom start (rom)
  442.   MOVE.L  A0,A5
  443.   SUB.L   D2,A5      -> A5=diff
  444.   MOVEQ   #26-2,D1   ->RT_SIZE-2,D1
  445.   SUB.L   D1,D0
  446.   MOVE.W  #$4AFC,D1  ->RTC_MATCHWORD,D1
  447.   fr_find:
  448.   SUBQ.L  #2,D0
  449.   BLS.B   fr_exit_nf
  450.   CMP.W   (A0)+,D1
  451.   BNE.B   fr_find
  452.   MOVEQ   #2,D2
  453.   ADD.L   (A0),D2    ->RT_MATCHTAG-2(A0),D2
  454.   ADD.L   A5,D2
  455.   CMP.L   A0,D2
  456.   BNE.B   fr_find
  457.   MOVE.L  12(A0),A1  ->RT_NAME-2(A0),A1
  458.   ADD.L   A5,A1
  459.   MOVE.L  A3,A2
  460.   fr_compare:
  461.   CMPM.B  (A2)+,(A1)+
  462.   BNE.B   fr_find
  463.   TST.B   -1(A2)
  464.   BNE.B   fr_compare
  465.  
  466.   MOVE.L  A0,D0
  467.   SUBQ.L  #2,D0
  468.  
  469.   fr_exit2:
  470.   MOVEM.L (A7)+,D1-D7/A0-A6
  471.   RTS
  472.  
  473.   fr_exit_nf:
  474.   MOVEQ   #0,D0
  475.   BRA.B   fr_exit2
  476.  
  477.  
  478. ->  IN: a0=ptr to ROM, d0=rom len, a1=ptr to module, d6=dosbase
  479. -> OUT: d0=success
  480. installmodule:
  481.   MOVEQ   #0,D0
  482.   RTS
  483.  
  484. ->  IN: a0=FmtString, a1=Array (may be 0), d6=dosbase
  485. printf:
  486.   EXG     D6,A6
  487.   MOVEM.L D0-D2/A0-A1,-(A7)
  488.   MOVE.L  A0,D1
  489.   MOVE.L  A1,D2
  490.   JSR     -$3BA(A6)   -> _LVOVPrintF
  491.   MOVEM.L (A7)+,D0-D2/A0-A1
  492.   EXG     D6,A6
  493.   RTS
  494.  
  495. ENDPROC
  496.  
  497.  
  498. PROC romresum(rom,size)
  499.   MOVE.L  rom,A0
  500.   MOVE.L  size,D0
  501.   MOVE.L  D0,D1
  502.   LSR.L   #2,D1
  503.   MOVE.L  -$18(A0,D0.L),D0
  504.   NOT.L   D0
  505.   rr_loop:
  506.   ADD.L   (A0)+,D0
  507.   BCC.B   rr_skip
  508.   ADDQ.L  #1,D0
  509.   rr_skip:
  510.   SUBQ.L  #1,D1
  511.   BNE.B   rr_loop
  512.   NOT.L   D0
  513. ENDPROC D0
  514.  
  515.